import static org.junit.Assert.*;

import java.util.Calendar;

import org.junit.Test;


public class IntegrationTest {
    Functions functions = new Functions(true);
    
    @Test
    public void testAddEvent() {
	InputParser parser = new InputParser("add ");
	Functions.deleteAll();
	try {
	    //Add event without urgent or reminder
	    try {
		parser.parse("add \"event task\" from \\8 aug\\ to \\9 aug\\", functions);
		Task t = InternalMemory.getEventTask().get(0);
		assertEquals(t.getDescription(), "event task");
		assertEquals(t.getTimeSpan().getStart().toString(), "Fri Aug 08 00:00:00 SGT 2014");
		assertEquals(t.getTimeSpan().getEnd().toString(), "Sat Aug 09 00:00:00 SGT 2014");
		assertFalse(t.getUrgent());
		assertFalse(t.getReminder().getReminderStatus());
	    } catch (Exception e) {
		assertTrue(false);
	    }

	    //Add event without reminder. Test for sorting. Urgent should be on top.
	    try {
		parser.parse("add \"event task 1\" from \\11 aug\\ to \\12 aug\\ urgent", functions);
		Task t = InternalMemory.getEventTask().get(0);
		assertEquals(t.getDescription(), "event task 1");
		assertEquals(t.getTimeSpan().getStart().toString(), "Mon Aug 11 00:00:00 SGT 2014");
		assertEquals(t.getTimeSpan().getEnd().toString(), "Tue Aug 12 00:00:00 SGT 2014");
		assertTrue(t.getUrgent());
		assertFalse(t.getReminder().getReminderStatus());
	    } catch (Exception e) {
		assertTrue(false);
	    }

	    //Add event without reminder. Check for clashing. Test for sorting. Earliest urgent on top.
	    try {
		parser.parse("add \"event task 2\" from \\10 aug 10pm\\ to \\12 aug 11.30pm\\ urgent", functions);

		//Test for clash
		parser = new InputParser("y");
		parser.parse("y", functions);

		Task t = InternalMemory.getEventTask().get(0);
		assertEquals(t.getDescription(), "event task 2");
		assertEquals(t.getTimeSpan().getStart().toString(), "Sun Aug 10 22:00:00 SGT 2014");
		assertEquals(t.getTimeSpan().getEnd().toString(), "Tue Aug 12 23:30:00 SGT 2014");
		assertTrue(t.getUrgent());
		assertFalse(t.getReminder().getReminderStatus());
	    } catch (Exception e) {
		assertTrue(false);
	    }

	    //Add event with reminder and without urgent. Event with latest end time should be at the bottom.
	    try {
		parser = new InputParser("add");
		parser.parse("add \"event task 3\" from \\20 aug 9am\\ to \\22 aug 12pm\\ reminder \\9 aug 9pm\\", functions);
		Task t = InternalMemory.getEventTask().get(3);
		assertEquals(t.getDescription(), "event task 3");
		assertEquals(t.getTimeSpan().getStart().toString(), "Wed Aug 20 09:00:00 SGT 2014");
		assertEquals(t.getTimeSpan().getEnd().toString(), "Fri Aug 22 12:00:00 SGT 2014");
		assertFalse(t.getUrgent());
		assertTrue(t.getReminder().getReminderStatus());
		assertEquals(t.getReminder().getReminderTime().toString(), "Sat Aug 09 21:00:00 SGT 2014");
	    } catch (Exception e) {
		assertTrue(false);
	    }

	    //Add event with start time later than end time. Exception should be caught and thrown.
	    try {
		parser = new InputParser("add");
		parser.parse("add \"event task 3\" from \\20 aug 9am\\ to \\11 aug\\", functions);
		assertTrue(false);
	    } catch (Exception e) {
		assertTrue(true);
	    }


	    //Add event with only start time. Exception should be caught and thrown.
	    try {
		parser = new InputParser("add");
		parser.parse("add \"event task 3\" from \\20 aug 9am\\", functions);
		assertTrue(false);
	    } catch (Exception e) {
		assertTrue(true);
	    }

	    //Add event with only end time. Exception should be caught and thrown.
	    try {
		parser = new InputParser("add");
		parser.parse("add \"event task 3\" to \\20 aug 9am\\", functions);
		assertTrue(false);
	    } catch (Exception e) {
		assertTrue(true);
	    }

	    //Add event with due by time and to time. Exception should be caught and thrown.
	    try {
		parser = new InputParser("add");
		parser.parse("add \"event task 3\" to \\20 aug 9am\\ due by \\12 aug\\", functions);
		assertTrue(false);
	    } catch (Exception e) {
		assertTrue(true);
	    }

	} catch (Exception e) {
	    assertTrue(false);
	}
    }

    @Test
    public void testAddMisc() {
   	InputParser parser = new InputParser("add ");
   	Functions.deleteAll();
   	try {
   	    try {
   		//Add without urgent
   		parser.parse("add \"test\"", functions);
   		Task t = InternalMemory.getMiscTask().get(0);
   		assertEquals(t.getDescription(), "test");
   		assertTrue(t.getTimeSpan().isMisc());
   	    } catch (Exception e) {
   		assertTrue(false);
   	    }
   	    
   	 try {
		//Add with reminder
		parser.parse("add \"test\" reminder\\8 aug 10.30pm\\", functions);
		Task t = InternalMemory.getMiscTask().get(1);
		assertEquals(t.getDescription(), "test");
		assertTrue(t.getTimeSpan().isMisc());
		assertEquals(t.getReminder().getReminderTime().toString(), "Fri Aug 08 22:30:00 SGT 2014");
	    } catch (Exception e) {
		assertTrue(false);
	    }
   	    
   	    try {  
   		//Add with urgent (and check sorting)
   		parser.parse("add \"test2\" urgent", functions);
   		Task t = InternalMemory.getMiscTask().get(0);
   		assertEquals(t.getDescription(), "test2");
   		assertTrue(t.getTimeSpan().isMisc());
   	    } catch (Exception e) {
   		assertTrue(false);
   	    }
   	    
	    
	    //Add without descriptiom. Should throw exception
   	    try{
   		parser.parse("add test2 urgent", functions);
   		assertTrue(false);
   	    } catch (Exception e) {
   		assertTrue(true);
   	    }

   	} catch (Exception e) {
   	    assertTrue(false);
   	}
       }
    
    @Test
    public void testAddDeadline() {
   	InputParser parser = new InputParser("add ");
   	Functions.deleteAll();
   	try {
   	    try{
   		//Add without urgent
   		parser.parse("add \"deadline 1\" due by \\11 aug\\", functions);
   		Task t = InternalMemory.getDeadlineTask().get(0);
   		assertEquals(t.getDescription(), "deadline 1");
   		assertEquals(t.getTimeSpan().getStart().toString(), "Mon Aug 11 00:00:00 SGT 2014");
   		assertFalse(t.getUrgent());
   	    } catch (Exception e) {
   		assertTrue(false);
   	    }
   	    
   	    try{ 
   		//Add with urgent without reminder
   		parser.parse("add \"deadline 2\" due by\\20 aug\\ urgent", functions);
   		Task t = InternalMemory.getDeadlineTask().get(0);
   		assertEquals(t.getDescription(), "deadline 2");
   		assertEquals(t.getTimeSpan().getStart().toString(), "Wed Aug 20 00:00:00 SGT 2014");
   		assertTrue(t.getUrgent());
   	    } catch (Exception e) {
   		assertTrue(false);
   	    }
   	    
   	   try{ 
  		//Add with earlier date to check sorting
  		parser.parse("add \"deadline 3\" due by\\9 aug\\ reminder\\7 aug\\", functions);
  		Task t = InternalMemory.getDeadlineTask().get(1);
  		assertEquals(t.getDescription(), "deadline 3");
  		assertEquals(t.getTimeSpan().getStart().toString(), "Sat Aug 09 00:00:00 SGT 2014");
  		assertFalse(t.getUrgent());
  	    } catch (Exception e) {
  		assertTrue(false);
  	    }
   	} catch (Exception e) {
   	    assertTrue(false);
   	}
    }
}
